package ro.dta.idbi.interfaces;

import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.List;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;

import uk.ac.ic.doc.automed.IntegrityException;
import uk.ac.ic.doc.automed.NotFoundException;

import com.mxgraph.model.mxGraphModel;

/**
 * Interface for integration projects
 * 
 * @author Tudor Dobrila
 * 
 */
public interface IProject {

	/**
	 * Save the integration project to disk and use the project's default save
	 * location, if known
	 */
	void save() throws TransformerException, ParserConfigurationException, IOException;

	/**
	 * Save the integration project to disk
	 * 
	 * @param fileName
	 *            XML file where to save the project
	 */
	void saveAs(String fileName) throws TransformerException, ParserConfigurationException,
			IOException;

	/**
	 * Get the path where this project is saved as an XML file
	 * 
	 * @return Path where the project is saved
	 */
	String getFileName();

	/**
	 * Set the file name where this project will be saved by default as an XML
	 * file
	 * 
	 * @param fileName
	 *            Path where project will be saved by default as XML file
	 */
	void setFileName(String fileName);

	/**
	 * Get the strategy used in the project
	 * 
	 * @return Strategy used in the integration project
	 */
	mxGraphModel getStrategy();

	/**
	 * Set the strategy used in this integration project
	 * 
	 * @param strategy
	 *            Strategy used in the integration project
	 */
	void setStrategy(mxGraphModel strategy);

	/**
	 * Get the current operation (i.e. CONFORMING, MERGING or IMPROVING) being
	 * performed in the project
	 * 
	 * @return Integration operation currently being performed
	 */
	IntegrationOperation getCurrentOperation();

	/**
	 * Get the current step in the integration process
	 * 
	 * Equals to -1 if project is in strategy definition phase, 0 or greater if
	 * it is in the integration process
	 * 
	 * @return Current step in the integration process
	 */
	int getCurrentStep();

	/**
	 * Increment the current step in the integration process
	 */
	void incCurrentStep();

	/**
	 * Check if there are any more steps to be executed in current project
	 * 
	 * @return True if there are steps that need to be executed, false otherwise
	 */
	boolean canAdvance();

	/**
	 * Advanced current project to next phase
	 * 
	 * @throws NotFoundException
	 * @throws IntegrityException
	 */
	void advance() throws NotFoundException, IntegrityException;

	/**
	 * Get the schemas that have be integrated in the current step
	 * 
	 * @return Set of schemas being integrated in current step
	 */
	List<String> getSchemasForCurrentStep();

	/**
	 * Get the schemas that have to be integrated in a given step, assuming the
	 * operation is CONFORMING
	 * 
	 * @param step
	 *            Step no. for which to retrieve set of schemas
	 * @return Set of schemas being integrated in a given step
	 */
	List<String> getSchemas(int step);

	/**
	 * Get the schemas that have to be integrated in a given step and a given
	 * operation
	 * 
	 * @param step
	 *            Step no. for which to retrieve set of schemas
	 * @param operation
	 *            Operation for which to retrieve the set of schemas (can be
	 *            CONFORMING, MERGING or IMPROVEMENT)
	 * @return Set of schemas being integrated in a given step and given
	 *         operation
	 */
	List<String> getSchemas(int step, IntegrationOperation operation);

	/**
	 * Get the strategy associated with the project as an image
	 * 
	 * @return Buffered image of the strategy
	 */
	BufferedImage getStrategyImage();

	/**
	 * Replace a schema in the current step items with another schema
	 * 
	 * Used to update an old schema with a new one, obtained after applying some
	 * transformation over the old schema
	 * 
	 * @param oldSchema
	 *            Name of schema to be replaced
	 * @param newSchema
	 *            Name of new schema, usually obtained after performing some
	 *            transformation over the old schema
	 * @param command
	 *            Name of the transformation applied over the old schema to
	 *            generate the new schema
	 */
	void replaceCrtStepItem(String oldSchema, String newSchema, String command);

	/**
	 * Check if the schema passed as parameter can be restored to a previous
	 * version
	 * 
	 * @param schema
	 *            Schema to check if it is restorable
	 * @return True if schema can be reversed, false otherwise
	 */
	boolean canUndo(String schema);

	/**
	 * Restore the schema with the name passed as parameter to the previous
	 * state
	 * 
	 * @param schema
	 *            Name of the schema to be restored
	 * @return Name of the restored schema, <i>null</i> if restore could not be
	 *         performed
	 * @throws NotFoundException
	 *             If the previous schema is not found
	 * @throws IntegrityException
	 *             If the integrity of the repository is broken
	 */
	IMemento undoSchema(String schema) throws NotFoundException, IntegrityException;

	/**
	 * Check if the current integration step is the last step (i.e. improving of
	 * the last schema)
	 * 
	 * @return True if the current integration step is the last step, false
	 *         otherwise
	 */
	boolean isLastStep();

}